﻿using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using Wams.Admin;

namespace Wams.Server
{
    public class Comms: WamsServerModule
    {
        public CloudQueue InstanceMsgQueue = null;
        public Thread PollingThread = null;
        public bool IsRunning = false;

        public Comms()
        {
            WamsCore.Init += WamsCore_Init;
            WamsCore.Shutdown += WamsCore_Shutdown;
        }

        void WamsCore_Init()
        {
            IsRunning = true;
            
            // Create the queue client
            CloudQueueClient queueClient = WamsCore.MainStorageAccount.CreateCloudQueueClient();

            // Retrieve a reference to a queue
            InstanceMsgQueue = queueClient.GetQueueReference(WamsMessage.GetQueueName(WamsCore.ContainerName, RoleEnvironment.DeploymentId, int.Parse(RoleEnvironment.CurrentRoleInstance.Id.Substring(RoleEnvironment.CurrentRoleInstance.Id.LastIndexOf('_') + 1))));
            if (!InstanceMsgQueue.CreateIfNotExists()) InstanceMsgQueue.Clear();

            PollingThread = new Thread(new ThreadStart(PollForMessages));
            PollingThread.Name = "WamsMsgPolling";
            PollingThread.IsBackground = true;
            PollingThread.Start();
        }

        private void PollForMessages()
        {
            while (IsRunning)
            {
                try
                {
                    string msg = "";
                    while (msg != null)
                    {
                        msg = ReadMsg();
                        if (msg != null) ProcessMessage(msg);
                    }
                }
                catch(Exception ex)
                {
                    Logger.Log(LogLevel.Error, "Ex when polling messages:\r\n" + ex.ToString());
                }
                Thread.Sleep(TimeSpan.FromSeconds(30));
                if (!IsRunning) break;
            }
        }

        public void ProcessMessage(string msg)
        {
            WamsMessage command = WamsMessage.Parse(msg);
            if (command == null) throw new ApplicationException(string.Format("Command {0} not understood.", msg));

            switch (command.Name)
            {
                case "synccontent": ((SyncContentMessage)command).Execute(); break;
                case "syncsettings": ((SyncSettingsMessage)command).Execute(); break;
                case "refreshresourcelist": ((RefreshResourceListMessage)command).Execute(); break;
                case "setbusystate": ((SetBusyStateMessage)command).Execute(); break;
                case "ping": ((PingMessage)command).Execute(); break;
                case "recycle": ((RecycleMessage)command).Execute(); break;
                case "synccertificates": ((SyncCertificatesMessage)command).Execute(); break;
            }
        }

        public string ReadMsg()
        {
            CloudQueueMessage msg = InstanceMsgQueue.GetMessage();
            if (msg == null) return null;
            InstanceMsgQueue.DeleteMessage(msg);
            return msg.AsString;
        }

        void WamsCore_Shutdown()
        {
            if (PollingThread != null) PollingThread.Abort();
            if (InstanceMsgQueue != null) InstanceMsgQueue.DeleteIfExists();
        }
    }
}